package com.neusoft.hifly.netty.websocket;

import org.springframework.kafka.core.KafkaTemplate;

import com.neusoft.hifly.core.log.Log;
import com.neusoft.hifly.netty.config.NettyConfig;
import com.neusoft.hifly.netty.websocket.handler.WebSocketServerInitialzer;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;

/**
 * Title: Netty服务
 * <p>
 * Description: Netty WebSocket服务
 * <p>
 * Copyright: 2019
 * <p>
 * Company: 辽宁畅通数据通信有限公司
 * 
 * @author
 * @version 1.0.0
 */
public class WebSocketServer {
	/**
	 * 启动WebSocket服务
	 * 
	 * @param nettyConfig
	 *            配置
	 * @param kafkaTemplate
	 *            kafka
	 * @throws Exception
	 *             异常
	 */
	public void start(NettyConfig nettyConfig, KafkaTemplate<String, Object> kafkaTemplate) throws Exception {
		// 定义一对线程组
		// 主线程组, 用于接受客户端的连接，
		EventLoopGroup mainGroup = new NioEventLoopGroup();
		// 从线程组, 负责IO交互工作
		EventLoopGroup subGroup = new NioEventLoopGroup();
		try {
			// netty服务器的创建, 辅助工具类，用于服务器通道的一系列配置
			ServerBootstrap server = new ServerBootstrap();
			// 绑定两个线程组
			server.group(mainGroup, subGroup)
					// 指定NIO的模式
					.channel(NioServerSocketChannel.class)
					// 子处理器，用于处理workerGroup
					.childHandler(new WebSocketServerInitialzer(nettyConfig.getWebSocketPath(), kafkaTemplate));

			// 输出日志
			if (nettyConfig.isLogEnabled()) {
				server.handler(new LoggingHandler(LogLevel.INFO));
			}

			// 启动server，并且设置8088为启动的端口号，同时启动方式为同步
			ChannelFuture future = server.bind(nettyConfig.getWebSocketPort()).sync();
			Log.info("WebSocket Server 启动成功! " + future.channel().localAddress());
			// 监听关闭的channel，设置位同步方式
			future.channel().closeFuture().sync();
		} finally {
			//退出线程组
			mainGroup.shutdownGracefully();
			subGroup.shutdownGracefully();
		}
	}
}
